#ifndef _ROW_
#define _ROW_ 1

#include <cstdint>
#include <cstdio>
#include <memory>

#define COLUMN_USERNAME_SIZE 32
#define COLUMN_EMAIL_SIZE 255

struct Row {
    uint32_t id;
    char username[COLUMN_USERNAME_SIZE + 1];
    char email[COLUMN_EMAIL_SIZE + 1];
    void print() {
        std::printf("(%d, %s, %s)\n", id, username, email);
        return ;
    }
};

#define size_of_attribute(Struct, Attribute) sizeof(((Struct*)0)->Attribute)

const uint32_t ID_SIZE = size_of_attribute(Row, id);
const uint32_t USERNAME_SIZE = size_of_attribute(Row, username);
const uint32_t EMAIL_SIZE = size_of_attribute(Row, email);
const uint32_t ID_OFFSET = 0;
const uint32_t USERNAME_OFFSET = ID_OFFSET + ID_SIZE;
const uint32_t EMAIL_OFFSET = USERNAME_OFFSET + USERNAME_SIZE;
const uint32_t ROW_SIZE = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;

/*     the layout of a serialized row
        column	  size (bytes)	offset
        id	        4	          0
        username  	33	          4
        email	    256	          37
        total	    293	 
*/

void serialize_row(Row& source, void* destination) {
    memcpy(destination + ID_OFFSET, &(source.id), ID_SIZE);
    memcpy(destination + USERNAME_OFFSET, source.username, USERNAME_SIZE);
    memcpy(destination + EMAIL_OFFSET, source.email, EMAIL_SIZE);
    return ;
}
void deserialize_row(void* source, Row* destination) {
    memcpy(&(destination->id), source + ID_OFFSET, ID_SIZE);
    memcpy(&(destination->username), source + USERNAME_OFFSET, USERNAME_SIZE);
    memcpy(&(destination->email), source + EMAIL_OFFSET, EMAIL_SIZE);
    return ;
}

#endif